#!/usr/bin/python
# -*- coding: utf-8 -*-
from itertools import count
import json
import logging
import os
import re
import subprocess
import threading
import time
import traceback
from concurrent.futures.thread import ThreadPoolExecutor
from datetime import datetime
from multiprocessing import Process

import requests

from automonkey.config import DefaultConfig
from .adb import AdbTool
from .exception import DeviceLockedFailed, DeviceNotConnectedException, InstallAppException, CheckScreenLockedFailed
from .logcat import LogCat
from .tcloud_update import TCloud
from .utils import Utils

logger = logging.getLogger(__name__)

"""
#  MonkeyRunner ， 多进程
"""


class PerformanceRunner(Process):

    def __init__(self, queue, lock, performance,ext=None):
        super(PerformanceRunner, self).__init__()
        self.queue = queue
        self.performance = performance
        self.lock = lock
        self.daemon = True
        self.logcat = None
        self.adb_tool = None
        self.tcloud = None
        self.process = 0
        self.airtest_config = {}
        self.running_status = 1
        self.running_error_reason = ''
        self.set_up_expend_time = 0  # 准备阶段耗时
        self.ext = ext

    def run(self):
        try:
            self.init_tools()

            # 开始测试
            self.tcloud.on_task_begin()

            # 测试准备
            self.setup()

            # 测试内容
            self.run_performances()

            # 测试结束
            self.teardown()

        except DeviceNotConnectedException as d_e:
            self.running_status = 2
            logger.error(d_e)
            self.performance.result.on_device_connect_failed()
            self.tcloud.on_device_connect(False)
        except CheckScreenLockedFailed as c_e:
            self.running_status = 2
            logger.error(c_e)
            self.performance.result.on_check_screen_lock_failed()
            self.tcloud.on_screen_lock(False)
        except InstallAppException as i_e:
            self.running_status = 2
            logger.error(i_e)
            self.performance.result.on_app_install_failed()
            self.tcloud.on_setup_install_app(False)
        except CheckScreenLockedFailed as s_e:
            self.running_status = 2
            logger.error(s_e)
            self.performance.result.on_check_screen_lock_failed()
            self.tcloud.on_screen_lock(False)
        except Exception as e:
            self.running_status = 2
            logger.error(e)
            traceback.print_exc()
        finally:
            self.tcloud.on_anr_crash_changed(100, 0, 0)
            if self.running_status == 2:
                self.tcloud.on_running_status(self.running_status, self.running_error_reason)
            logger.info('{} 结束测试 设备 {}'.format(self.pid, self.performance.device.device_id))
            # 测试结束
            self.tcloud.release_monkey_device(self.performance.device.device_id)
            # 断开连接设备
            self.performance.device.disconnect()
            self.publish_result()

    # 超时退出,runner外部进程对象来调用
    def timeout_exit(self, state, error_msg):
        try:
            logger.info('{},设备{} 超时，外部强制结束'.format(self.pid, self.performance.device.device_id))
            if self.tcloud is not None:
                self.tcloud.on_running_status(state, error_msg)
                self.teardown()
                self.publish_result()
        except Exception as e:
            logger.error(e)
            traceback.print_exc()
        finally:
            self.terminate()

    def get_performance_airtest_scripts(self):
        try:
            os.system('rm -rf ./performancetest')
            os.system('git clone https://gitee.com/coutliuxing/airtest.git ./performancetest')
            os.system('cp -rf ./performancetest/* ./')
        except Exception as e:
            logger.error(e)
        # logger.info("get_performance_airtest_scripts")

    def run_performances(self):
        try:
            if self.performance.result.setup_install_result and self.performance.result.start_app_status and self.performance.result.check_screen_locked:

                if self.on_user_cancel():
                    self.tcloud.on_user_cancel_stask_success()
                    return
                self.running_status = 1
                self.tcloud.on_running_status(self.running_status, "")
                self.run_performance(self.performance.config.config_json)
            else:
                logger.info("({}) 安装/启动 APP 失败，取消测试".format(self.performance.device.device_id))
                self.running_status = 2
                self.tcloud.on_running_status(self.running_status, self.running_error_reason)
                self.tcloud.on_anr_crash_changed(100, 0, 0)

        except Exception as e:
            logger.error(e)
            logger.error(traceback.format_exc())

    def run_performance(self, config_json):
        try:
            script_paths = config_json["script_paths"]

            for script in script_paths:
                script["path"] = os.path.join(config_json["root"], script["path"])

            logger.info("{} script_paths = {}".format(self.performance.device.device_id, script_paths))

            airtest_log_txt = "{}/{}/{}".format(self.local_report_path, self.performance.device.device_id,
                                                "airtest_log.txt")

            if os.path.exists(os.path.dirname(airtest_log_txt)) is False:
                os.makedirs(os.path.dirname(airtest_log_txt))

            test_name = config_json["test_name"]
            self.performance_test_id = self.tcloud.create_performance_test(test_name, self.performance.config.run_time,
                                                                           self.performance.result.install_time,
                                                                           self.performance.result.start_up_time)
            performance_progress = self.run_performance_cmd(script_paths, test_name, airtest_log_txt)

            time_begin = datetime.now()

            running_status = 1
            running_error_reason = ''
            cancel_flag = False

            time.sleep(5)
            # with ThreadPoolExecutor() as executor:
            #     executor.submit(self.getCpuAndMemory(performance_progress))
            # executor.submit(self.runProcss(performance_progress))

            start_time = time.time()
            airtest_log_list = []
            while performance_progress.poll() is None:
                try:
                    # line = performance_progress.stdout.readline()
                    # airtest_log_list.append(str(line))
                    # logger.info(
                    #     "{}{}".format(self.performance.device.device_id, line))
                    time.sleep(60)
                    self.send_boom_msg()
                    if (time.time() - start_time) > (self.performance.config.run_time * 60 - self.set_up_expend_time):
                        running_status = 2
                        running_error_reason = "运行时间已超限制时间({}) ".format(self.performance.config.run_time)
                        performance_progress.kill()
                        break

                    cancel_flag = self.on_user_cancel()  # 检测是否 进行了 中断操作
                    if cancel_flag:
                        performance_progress.kill()
                        break

                    # 如果已经解锁，在任务期间保持亮屏
                    if(self.performance.result.check_screen_locked):
                        # self.adb_tool.wakeup_screen()
                        # 通过点击保持长亮
                        Utils.command_execute("{} input motionevent DOWN -100 -100".format(self.adb_tool.adb_command))
                    
                    # 警告：airtest运行期间，尽量不要使用其他adb去连接
                    if(not self.check_and_retry_connect_device()):
                        running_error_reason = 'device {} dis connect'.format(self.performance.device.device_id)
                        running_status = 2
                        logger.warning('{} 设备连接中断'.format(self.performance.device.device_id))
                        self.tcloud.on_device_disconnect_on_running()
                        break

                    # 性能分析上报，由于云测性能分析功能基本没用，所以暂停上报
                    # logger.info('self.get_cpu_rss_heap()')
                    # self.get_cpu_rss_heap()
                
                except Exception as ex:
                    logger.error(ex)
                    break

            logger.info("performance_progress.poll() = {}".format(performance_progress.poll()))

            if os.path.exists(airtest_log_txt):
                logger.info("{} 打印airtest运行日志".format(self.performance.device.device_id))
                with open(airtest_log_txt, "r") as f:
                    data = f.read()
                    logger.info("{} {}".format(self.performance.device.device_id, data))
                    f.close()

            airtest_error_log = "{}/{}/{}".format(self.local_report_path, self.performance.device.device_id,
                                                  "airtest_error_log.txt")

            if os.path.exists(airtest_error_log):
                logger.info("脚本运行异常,反馈状态")
                running_status = 2
                running_error_reason = running_error_reason + "脚本运行异常 "

            time.sleep(30)  # 此处的需要等待 log 写入

            monkey_logs = []

            # user cancel here
            if cancel_flag:
                self.tcloud.on_user_cancel_stask_success()
            elif running_status == 2:
                self.tcloud.on_running_status(running_status, running_error_reason)

            self.performance.result.log_path = self.logcat.get_logcat_log(monkey_logs)

            # calculate every test's average and top
            self.tcloud.calculate_performance_test(self.performance_test_id)

            self.tcloud.on_anr_crash_changed(70, 0, 0)


            # 上传报告
            self.upload_report_files()
            # 媒体数据 
            self.media_reports = self.check_sdk_media_report()
            self.media_reports= str(self.media_reports)
            logger.info('media_reports:{}'.format(self.media_reports))

            self.tcloud.on_anr_crash_changed(80, 0, 0)
            self.upload_bug_report_url()
            self.upload_airtest_report_url()
            self.tcloud.on_anr_crash_changed(90, 0, 0)
            time.sleep(10)

        except Exception as e:
            self.running_status = 2
            self.tcloud.on_running_status(self.running_status, self.running_error_reason)
            logger.error("run_performance->",e)
            logger.error(traceback.format_exc())
        # finally:
        #     self.teardown()

    # 当检测到设备断开的时候，尝试多次重连
    def check_and_retry_connect_device(self,retry =5):
        if isinstance(self.performance.device.connect(), DeviceNotConnectedException):
            if(retry<=0):
                return False
            time.sleep(15)
            retry = retry - 1
            self.check_and_retry_connect_device(retry)
        return True;

        # 配置android boomsdk的触发器事件
    def send_boom_msg(self):
        self.adb_tool.shell("am broadcast -a com.hardy.boom.task --es task_id {}".format(self.performance.task_id))

    # 性能分析上报，由于云测性能分析功能基本没用，所以暂停上报
    def get_cpu_rss_heap(self):
        cpu, rss = self.adb_tool.get_cpu(self.performance.config.package_name)
        heap_size, heap_alloc = self.adb_tool.get_memory_info(self.performance.config.package_name)
        logger.info([cpu, rss, heap_size, heap_alloc])
        self.tcloud.upload_realtime_log(self.performance_test_id, cpu, rss, heap_size, heap_alloc)

    def on_user_cancel(self):
        cancel_status = self.tcloud.get_monkey_cancel_status(self.performance.task_id)
        logger.info(cancel_status)
        if cancel_status in ['0', 0]:
            logger.warning('[{}] here find the cancel from the tcloud, stop the performance now!'.
                           format(self.performance.device.device_id))
            running_error_reason = 'cancel by user!'
            # on user cancel
            self.tcloud.on_user_cancel_task()
            cancel_flag = True
        else:
            cancel_flag = False
        return cancel_flag

    def run_performance_cmd(self, script_paths, test_name, stdout_file_path):

        self.airtest_config = {
            "script_paths": script_paths,
            "device": {
                "host": self.performance.device.adb_ip,
                "port": "5037",
                "device": self.performance.device.device_id,
                "recording": False,
                "uninstall": False,
                "log_path": self.performance.device.device_id,
                "permission_allow_button": ["com.android.packageinstaller:id/permission_allow_button",
                                            "com.android.permissioncontroller:id/permission_allow_button"],
                "order_allow_button": [{
                    "id": "android:id/button3",
                    "text": "确定"
                }, {
                    "id": "android:id/button3",  # 华为系统更新
                    "text": "稍后"
                }, {
                    "id": "android:id/button1",  # 处理Android 10 SDK=22的弹窗
                    "text": "确定"
                }, {
                    "id": "android:id/button1",  # 魅族权限
                    "text": "始终允许"
                }, {
                    "id": "android:id/button1",  # 小米权限
                    "text": "允许"
                }]
            },
            "app": {
                "package_name": self.performance.config.package_name,
                "main_activity": self.performance.config.default_app_activity,
                "apk_path": ""
            },
            "workspace": self.local_performance_path + "_" + test_name + ".log",
            "log_path": self.local_report_path,
            "app_log": "app_log.txt",
            "airtest_error_log": "airtest_error_log.txt",
            "report_static_root": "http://192.168.8.241:8069/report/"
        }
        data_json = json.dumps(self.airtest_config)
        logger.info("airtest--->" + data_json)
        config_file = os.path.join(self.local_report_path, self.performance.device.device_id, "config.json")
        config_file_parent = os.path.dirname(config_file)
        if not os.path.exists(config_file_parent):
            os.makedirs(config_file_parent)

        with open(config_file, "w+") as f:
            f.write(data_json)
            f.flush()
            f.close()
        # 开始执行
        logger.info('({}) 开始运行 performance 测试'.format(self.performance.device.device_id))

        command = "python3 -m airtesttask --config %s" % config_file

        logger.info('({}) 开始运行 性能 测试'.format(self.performance.device.device_id))

        monkey_progress = subprocess.Popen(command, shell=True, stdout=open(stdout_file_path, "w+"),
                                           stderr=subprocess.STDOUT,
                                           executable="/bin/bash")
        return monkey_progress

    def setup_air_test(self):
        if self.performance.config.test_envs.get('setup') is not None:
            logger.info('({}) 开始运行 性能 测试 init'.format(self.performance.device.device_id))
            case_path = '{}/{}'.format(self.performance.config.test_envs.get('root'),
                                       self.performance.config.test_envs.get('setup').get('path'))

            command = 'python3 -m airtest run {} --device Android://{}:5037/{} ' \
                      ''.format(case_path, self.performance.device.adb_ip, self.performance.device.device_id)
            p = self.adb_tool.run_performance(command)
            result = self.adb_tool.output(p)
            logger.info("\n".join(result))
            self.adb_tool.set_system_default_input(key=self.performance.config.test_envs.get('setup').get('input'))

    # 上传airtest的报告地址
    def upload_airtest_report_url(self):
        try:
            now = datetime.now().strftime("%Y-%m-%d")

            script_name = os.path.basename(self.airtest_config["script_paths"][0]["path"])
            script_name_1 = script_name.split(".")[0]
            build_number = os.environ.get('BUILD_NUMBER')
            zip_url = '{}/monkey/{}/{}/logcat/{}/{}'.format(DefaultConfig.OSS_MONKEY_URL,
                                                            now, build_number,
                                                            self.pid, '{}.zip'.format(self.pid))

            log_path = "{}/{}/{}/1/{}.log/log.html".format(self.local_report_path, self.airtest_config["device"]
            ["device"], script_name, script_name_1)
            if os.path.exists(log_path):
                report_url = '{}/monkey/{}/{}/logcat/{}/{}/{}/1/{}.log/log.html'.format(DefaultConfig.OSS_MONKEY_URL,
                                                                                        now, build_number,
                                                                                        self.pid,
                                                                                        self.airtest_config["device"][
                                                                                            "device"], script_name,
                                                                                        script_name_1)
            else:
                report_url = '{}/monkey/{}/{}/logcat/{}/{}/app_log.txt'.format(DefaultConfig.OSS_MONKEY_URL,
                                                                               now, build_number,
                                                                               self.pid,
                                                                               self.airtest_config["device"][
                                                                                   "device"])
            report_type = 4
            self.tcloud.on_report_upload(report_url, report_type, zip_url)
        except Exception as  e:
            logger.error(e)
            logger.error(traceback.format_exc())

    # 获取并生成,上传bug report（adb bug report)和上传airtest报告文件
    def upload_report_files(self):
        self.logcat.generate_logcat()
        # self.logcat.get_bug_report_log()
        # self.logcat.generate_bug_report()
        self.logcat.upload_report_log_in_zip()

    # 上传bug report url 地址
    def upload_bug_report_url(self):
        try:
            now = datetime.now().strftime("%Y-%m-%d")
            build_number = os.environ.get('BUILD_NUMBER')
            report_url = '{}/monkey/{}/{}/logcat/{}/bug_report_out/index.html'.format(DefaultConfig.OSS_MONKEY_URL,
                                                                                      now, build_number, self.pid)
            report_type = 1
            self.tcloud.on_report_upload(report_url, report_type)
        except Exception as e:
            logger.error(e)
            logger.error(traceback.format_exc())

    def upload_other_report(self):
        try:
            now = datetime.now().strftime("%Y-%m-%d")
            build_number = os.environ.get('BUILD_NUMBER')
            # monkey.log
            report_url_pre = '{}/monkey/{}/{}/logcat/{}'.format(DefaultConfig.OSS_MONKEY_URL, now, build_number,
                                                                self.pid)

            self.tcloud.on_report_upload(report_url='{}/monkey.log'.format(report_url_pre), report_type=2)

        except Exception as e:
            logger.error(e)
            logger.error(traceback.format_exc())

    def publish_result(self):
        self.lock.acquire()
        self.queue.put(self.performance)
        self.lock.release()

    def init_tools(self):
        self.adb_tool = AdbTool(self.performance.device.adb_ip, self.performance.device.device_id)
        self.tcloud = TCloud(self.performance.task_id, self.performance.device.device_id, self.performance.monkey_id,
                             self.performance.tcloud_url)

        self.local_performance_path = '{}/{}/{}'.format(DefaultConfig.LOCAL_LOGCAT_PATH, self.pid, 'performance')
        # airtest当前跑的设备导出的报告路径 eg: {self.local_report_path}/RFCMB02RRHJ/test3.air/1/test3.log/log.html
        self.local_report_path = '{}/{}'.format(DefaultConfig.LOCAL_LOGCAT_PATH, self.pid)
        self.local_logcat_path = '{}/{}/{}'.format(DefaultConfig.LOCAL_LOGCAT_PATH, self.pid, 'logcat.log')

    def on_process_changed(self, time_temp, test_count, run_count):
        logger.info('({}) time now ... {}'.format(self.performance.device.device_id, time_temp))
        self.process = int(time_temp / (self.performance.config.run_time * 60.00) * 100.00)
        logger.info('({}) process now : {}'.format(self.performance.device.device_id, self.process))

        if self.process <= 0:
            self.process = 0

        if self.process >= 100:
            self.process = 100

        logger.info(
            '''current information <{}> {}'''.format(datetime.now().strftime('%Y.%m.%d %H:%M:%S'), self.process))
        self.tcloud.on_anr_crash_changed((run_count * 100 + self.process) // test_count, 0, 0)

    def setup(self):
        try:
            set_up_start_time = time.time()

            logger.info('{} 开始测试 设备 {}'.format(self.pid, self.performance.device.device_id))

            # 清除 重建 logs
            self.clear_local_logs()
            self.creat_local_log_path()

            # 连接设备
            count = 4
            while(count>0):
                self.performance.result.device_connect_result = self.performance.device.connect()
                if(self.performance.result.device_connect_result):
                    break
                count = count -1
                time.sleep(15)

            if isinstance(self.performance.result.device_connect_result, DeviceNotConnectedException):
                self.running_error_reason = "设备连接失败"
                raise DeviceNotConnectedException

            # 锁定机器
            if(self.tcloud.using_monkey_device(self.performance.device.device_id)):
                raise DeviceLockedFailed

            # 开启日志
            self.logcat = LogCat(self.performance.device.adb_ip, self.performance.device.device_id, self.pid)

            # 测试开始时间
            self.performance.result.on_case_begin()

            # 检查 设备锁屏状态
            self.performance.result.check_screen_locked = self.adb_tool.check_screen_locked
            if not self.performance.result.check_screen_locked:
                logger.info("{} 尝试解锁".format(self.performance.device.device_id))
                self.performance.result.check_screen_locked = self.unlock_device_screen()

            self.tcloud.on_screen_lock(self.performance.result.check_screen_locked)
            if not self.performance.result.check_screen_locked:
                self.running_status = 2
                self.running_error_reason = "设备已锁屏，取消测试"
                raise CheckScreenLockedFailed

            self.tcloud.on_device_connect(True)

            # 清理缓存
            self.clear_log_on_device()

            self.adb_tool.close_app('com.netease.open.pocoservice')

            # TODO 暂时在这里删掉机器内的pocoservice
            # if self.adb_tool.check_package_installed('com.netease.open.pocoservice'):
            #     self.adb_tool.uninstall_package('com.netease.open.pocoservice')
            #
            # if self.adb_tool.check_package_installed('com.netease.open.pocoservice.test'):
            #     self.adb_tool.uninstall_package('com.netease.open.pocoservice.test')

            if self.adb_tool.check_package_installed('com.netease.open.pocoservice'):
                self.adb_tool.uninstall_package('com.netease.open.pocoservice')

            logger.info("{} 检查是否存在 airtest插件APK".format(self.performance.device.device_id))
            airtest_apk_basepath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "tools",
                                                "airtest_apk")
            logger.info("airtest_apk_basepath = {}".format(airtest_apk_basepath))
            if not self.adb_tool.check_package_installed("com.netease.nie.yosemite"):
                result = self.adb_tool.install_package(os.path.join(airtest_apk_basepath, "Yosemite.apk"),
                                                       "com.netease.nie.yosemite")
            # self.tcloud.on_anr_crash_changed(5, 0, 0)
            #
            # if not self.adb_tool.check_package_installed("com.netease.open.pocoservice"):
            #     result = self.adb_tool.install_package(os.path.join(airtest_apk_basepath, "pocoservice-debug.apk"),
            #                                         "com.netease.open.pocoservice")
            # self.tcloud.on_anr_crash_changed(10, 0, 0)
            # if not self.adb_tool.check_package_installed("com.netease.open.pocoservice.test"):
            #     result = self.adb_tool.install_package(
            #         os.path.join(airtest_apk_basepath, "pocoservice-debug-androidTest.apk"),
            #         "com.netease.open.pocoservice.test")
            # self.tcloud.on_anr_crash_changed(15, 0, 0)
            # if not self.adb_tool.check_package_installed("jp.co.cyberagent.stf.rotationwatcher"):
            #     result = self.adb_tool.install_package(os.path.join(airtest_apk_basepath, "RotationWatcher.apk"),
            #                                            "jp.co.cyberagent.stf.rotationwatcher")
            self.tcloud.on_anr_crash_changed(20, 0, 0)

            if self.performance.config.uninstall_app_required:
                # 卸载
                self.performance.result.setup_uninstall_result = self.adb_tool.uninstall_package(
                    self.performance.config.package_name)
                self.tcloud.on_setup_uninstall_app(self.performance.result.setup_uninstall_result)

            if self.performance.config.install_app_required:
                # 安装 package
                install_start_time = time.time()
                pipe_file = '{}/{}/{}'.format(DefaultConfig.LOCAL_LOGCAT_PATH, self.pid, 'pipe_file.txt')
                if os.path.exists(os.path.dirname(pipe_file)) is False:
                    os.makedirs(os.path.dirname(pipe_file))
                    # ,network_path=self.ext.app_download_url
                self.performance.result.setup_install_result = self.adb_tool.install_apk_with_pm(self.performance.config.local_package_path, 
                self.performance.config.package_name,network_path=self.ext.app_download_url, pipe_file=pipe_file)
                self.performance.result.install_time = int(time.time() - install_start_time)
            else:
                self.performance.result.setup_install_result = True

            self.tcloud.on_setup_install_app(self.performance.result.setup_install_result)

            if not self.performance.result.setup_install_result:
                self.running_error_reason = "安装APK 失败，取消测试"
                return

            self.tcloud.on_anr_crash_changed(30, 0, 0)

            # 获取 app 版本
            self.performance.result.app_version = self.adb_tool.get_package_version(
                self.performance.config.package_name)

            self.tcloud.on_get_app_version(self.performance.result.app_version)

            time.sleep(5)

            # 回到桌面
            logger.info('({}) 回到桌面'.format(self.performance.device.device_id))
            self.adb_tool.back_to_home()
            time.sleep(5)

            self.tcloud.on_anr_crash_changed(35, 0, 0)

            # 热启动 app
            logger.info('({}) 测试APP启动'.format(self.performance.device.device_id))
            self.performance.result.start_app_status, self.performance.result.start_up_time = \
                self.adb_tool.start_app_time(
                    self.performance.config.package_name,
                    self.performance.config.default_app_activity)
            self.tcloud.on_start_app(self.performance.result.start_app_status)

            if self.performance.result.start_app_status:
                logger.info('({}) 测试APP启动->成功,进行关闭'.format(self.performance.device.device_id))
                # self.adb_tool.close_app(self.performance.config.package_name)
                # self.adb_tool.clear_package_cache_data(self.performance.config.package_name)
            else:
                self.running_error_reason = "启动 APP 失败，取消测试"
                logger.info('({}) App 启动失败'.format(self.performance.device.device_id))

            self.tcloud.on_anr_crash_changed(40, 0, 0)

            # 登陆 app 没有用到！
            self.performance.result.login_app_status = self.try_to_login_app()
            self.tcloud.on_login_app(self.performance.result.login_app_status)

            self.set_up_expend_time = time.time() - set_up_start_time
            logger.info("{} 准备阶段耗时 {}".format(self.performance.device.device_id, self.set_up_expend_time))
        except Exception as e:
            self.running_status = 2
            logger.error(e)
            traceback.print_exc()
            raise e

    # 热启动app
    # def hot_start_app(self,retry=5):
    #     # 热启动 app
    #     logger.info('({}) 测试APP启动'.format(self.performance.device.device_id))
    #     self.performance.result.start_app_status, self.performance.result.start_up_time = \
    #         self.adb_tool.start_app_time(
    #             self.performance.config.package_name,
    #             self.performance.config.default_app_activity)
    #     self.tcloud.on_start_app(self.performance.result.start_app_status)

    #     if self.performance.result.start_app_status:
    #         logger.info('({}) 测试APP启动->成功,进行关闭'.format(self.performance.device.device_id))
    #         self.adb_tool.close_app(self.performance.config.package_name)
            
    #     else:
    #         if(retry<=0):
    #             self.running_error_reason = "启动 APP 失败，取消测试"
    #             logger.info('({}) App 启动失败'.format(self.performance.device.device_id))
    #         else:
    #             time.sleep(4)
    #             retry = retry -1
    #             self.hot_start_app(retry)

    def unlock_device_screen(self,retry=3):
        try:
            self.adb_tool.unlock_screen()
            time.sleep(3)
            while(not self.adb_tool.check_screen_locked and retry>0):
                retry=retry-1
                self.adb_tool.unlock_screen()
            time.sleep(3)
        except Exception as ex:
            if(retry<=0):
                raise ex
        return self.adb_tool.check_screen_locked

    def teardown(self):
        try:
            self.tcloud.on_anr_crash_changed(100, 0, 0)
            # update task end info
            self.process = 100
            self.tcloud.on_task_end(process=self.process, run_time=self.performance.config.run_time,ext=self.media_reports)

            logger.info('{} 结束测试 设备 {}'.format(self.pid, self.performance.device.device_id))
            # 测试结束时间
            self.performance.result.on_case_end()

            # 测试完了卸载掉pocoservice, 不然可能下次手机使用poco有问题
            if self.adb_tool.check_package_installed('com.netease.open.pocoservice'):
                self.adb_tool.uninstall_package('com.netease.open.pocoservice')

            # if self.adb_tool.check_package_installed('com.netease.open.pocoservice.test'):
            #     self.adb_tool.uninstall_package('com.netease.open.pocoservice.test')

            if self.performance.result.teardown_uninstall_result == '':
                if self.adb_tool.check_package_installed(self.performance.config.package_name):
                    if self.adb_tool.uninstall_package(self.performance.config.package_name):
                        self.performance.result.teardown_uninstall_result = 1
                    else:
                        self.performance.result.teardown_uninstall_result = 2
                else:
                    self.performance.result.teardown_uninstall_result = 0
                self.tcloud.on_teardown_uninstall_app(self.performance.result.teardown_uninstall_result)

            self.tcloud.release_monkey_device(self.performance.device.device_id)

            # 断开连接设备
            self.performance.device.disconnect()
        except Exception as e:
            logger.error(e)
            traceback.print_exc()
        finally:
            self.tcloud.release_monkey_device(self.performance.device.device_id)

    def check_sdk_media_report(self):
        # 解析logcat找到媒体的标记
        media_reports = []
        try:
            logcat_progess =  self.adb_tool.shell("cat /sdcard/Download/mediaTest/{}.txt".format(self.performance.config.package_name))

            media_reports = logcat_progess.stdout.readlines()
        except Exception as ex:
            logger.error(ex)      
        finally:
            self.adb_tool.shell("rm -rf /sdcard/Download/mediaTest/{}.txt".format(self.performance.config.package_name))       
        return media_reports

    def clear_log_on_device(self):
        # 移除 设备中原有的 log /sdcard 下的log
        self.adb_tool.clear_logcat()
        self.adb_tool.remove_file('/sdcard/crash-dump.log')
        self.adb_tool.remove_file('/sdcard/oom-traces.log')
        self.adb_tool.remove_file('/sdcard/MonkeyLog')
        self.logcat.reset_bug_report_log()

    def clear_local_logs(self):
        # 移除本地logcat 目录
        logger.info('移除 logcat 目录')
        Utils.command_execute('rm -rf ./logcat')

    def creat_local_log_path(self):
        logger.info('初始化 log 目录')

        Utils.command_execute('mkdir -p logcat')
        Utils.command_execute('mkdir -p logcat/{}'.format(self.pid))

    def try_to_unlock_screen(self):
        logger.info('({}) 尝试 解锁屏幕'.format(self.performance.device.device_id))
        # TODO

    def try_to_login_app(self):
        logger.info('({}) 尝试 登陆 app {}'.format(self.performance.device.device_id, self.performance.config.package_name))
        # TODO
        try:
            if self.performance.config.login_required:
                logger.info('({}) 使用 [{} ,{}] 尝试登陆'.format(self.performance.device.device_id,
                                                           self.performance.config.login_username,
                                                           self.performance.config.login_password))
                return True
            else:
                logger.info('({}) 不需要登陆'.format(self.performance.device.device_id))
                return True
        except Exception as e:
            logger.error(e)
            logger.error(traceback.format_exc())
            return False
